Skip to content

Avoid deadlocks in geometric repacking on windows#903

Merged
dscho merged 2 commits intomicrosoft:vfs-2.54.0from
dscho:avoid-deadlocks-in-geometric-repacking-on-windows
Apr 28, 2026
Merged

Avoid deadlocks in geometric repacking on windows#903
dscho merged 2 commits intomicrosoft:vfs-2.54.0from
dscho:avoid-deadlocks-in-geometric-repacking-on-windows

Conversation

@dscho
Copy link
Copy Markdown
Member

@dscho dscho commented Apr 28, 2026

This is a companion of gitgitgadget#2103 and of git-for-windows#6215.

On Windows, maintenance_task_geometric_repack() opens pack index files via pack_geometry_init() (which mmap()s the .idx files), then spawns git repack as a child process without setting child.odb_to_close. The parent's mmap()s prevent the child from deleting old .idx files.

On Windows 10 builds before the POSIX delete semantics change (between Build 17134.1304 and 18363.657, see https://stackoverflow.com/a/60512798), this results in Unlink of file '.git/objects/pack/pack-<hash>.idx' failed. Should I try again? during fetch-triggered auto-maintenance with the geometric strategy.

The fix adds the missing child.odb_to_close = the_repository->objects line, matching all other maintenance tasks.

The first commit introduces a GIT_TEST_LEGACY_DELETE environment variable to simulate legacy (pre-POSIX) delete semantics on modern Windows, so the regression test can verify the fix even on Windows 11.

dscho added 2 commits April 28, 2026 02:25
At some point between Windows 10 Build 17134.1304 and Build 18363.657,
the default behavior of `DeleteFileW()` was changed to use POSIX
semantics (https://stackoverflow.com/a/60512798). Under those semantics,
a file can be deleted even when another process holds an active
`MapViewOfFile` view on it: the directory entry is removed immediately,
but the underlying data persists until the last handle is closed.

On older Windows versions (and Windows 10 builds before that change),
`DeleteFileW()` uses legacy semantics where deletion fails outright if
any process holds a file mapping.

To allow testing code paths that depend on the legacy behavior, introduce
a `GIT_TEST_LEGACY_DELETE` environment variable. When set, `mingw_unlink()`
uses `SetFileInformationByHandle()` with `FileDispositionInfo` (the
non-POSIX variant) instead of `DeleteFileW()`, forcing legacy delete
semantics regardless of the Windows version.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
As is done for all the other maintenance tasks, let's release the ODB
also before starting the geometric repacking. That way, the `.idx` files
won't be `mmap()`ed when they are to be deleted (which does not work on
Windows because you cannot delete files on that platform as long as they
are kept open by a process).

This regression was introduced by 9bc1518 (builtin/maintenance:
introduce "geometric-repack" task, 2025-10-24), but was only noticed
once geometric repacking was made the default in 452b12c (builtin/
maintenance: use "geometric" strategy by default, 2026-02-24).

The fix recapitulates my work from df76ee7 (run-command: offer to
close the object store before running, 2021-09-09) & friends.

To guard against future regressions of this kind, add a check to
`run_and_verify_geometric_pack()` in `t7900` that detects orphaned
`.idx` files left behind after repacking. Contrary to interactive
calls, the `git maintenance` call in that test case would _not_ block on
Windows, asking whether to retry deleting that file, which is the reason
why this bug was not caught earlier.

Furthermore, since the default behavior of `DeleteFileW()` was changed
at some point between Windows 10 Build 17134.1304 and Build 18363.657
to use POSIX semantics (see https://stackoverflow.com/a/60512798),
the added orphaned-`.idx` check would be insufficient to catch this
regression on modern Windows without emulating legacy delete semantics
via `GIT_TEST_LEGACY_DELETE=1`.

This fixes git-for-windows#6210.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
@dscho dscho self-assigned this Apr 28, 2026
@dscho dscho merged commit d1778a9 into microsoft:vfs-2.54.0 Apr 28, 2026
107 of 109 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants